/**
 * @俄罗斯方块成员生成函数
 */
// ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
// ts接口
import {
  TetrisItemObjItem,
  TetrisItemObjItemStateObjItem,
  TetrisItemObjItemStateObjItems,
  InitializationTetrisItem,
  InitializationTetrisItemReturn,
} from '../interface/tetrisItemInterface'

// 引入公共方法
// ------------------------------------------------------------------------------
import { randomNum, deepClone } from '../../../utils/index'

// 引入俄罗斯方块专属变量
// ------------------------------------------------------------------------------
import {
  tetrisItemList,
  tetrisItemObj,
  tetrisItemColor,
} from './tetrisItemData'

/**
 * @俄罗斯方块成员生成函数
 */
// ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
const tetrisItemGenerate = () => {
  // 先获取到需要随机筛选的成员名称
  const obtainItemName = tetrisItemList[randomNum(0, tetrisItemList.length - 1)]

  // 获取到随机筛选出来的对应方块类型
  // ================================================================
  const obtainItem: TetrisItemObjItem = deepClone(tetrisItemObj[obtainItemName])

  // 获取到方块类型的名称
  // ================================================================
  const obtainItemStateName =
    obtainItem.stateList[randomNum(0, obtainItem.stateList.length - 1)]

  // 获取随机筛选出方块类型中的对应状态
  // ================================================================
  const obtainItemState: TetrisItemObjItemStateObjItem =
    obtainItem.stateObj[obtainItemStateName]

  // 筛选出本次展示成员的颜色信息
  // ================================================================
  const itemColor = tetrisItemColor[randomNum(0, tetrisItemColor.length - 1)]

  // 导出本次筛选出来的数据对象
  // ================================================================
  return deepClone({
    name: obtainItemName, // 随机筛选的成员名称
    stateName: obtainItemStateName, // 方块类型的状态名称
    ...obtainItemState, // 随机筛选出方块类型中的对应状态数组
    stateListLength: obtainItem.stateList.length, // 方块类型的状态名称规则数组长度
    color: itemColor, // 本次展示成员的颜色信息
  })
}

/**
 * @俄罗斯方块成员初始化函数
 * @portrait中心点纵
 * @transverse中心点列
 */
// ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
export const initializationTetrisItem: InitializationTetrisItem = (
  portrait: number = 0,
  transverse: number = 0
) => {
  // 获取到生成的成员并结构出里面需要的参数
  // ================================================================
  let {
    name, // 筛选的成员名称
    stateName, // 方块类型的名称
    stateListLength, // 方块类型的长度
    color, // 颜色
    allSpot, // 总的坐标数
    leftSpot, // 最左边的坐标数
    rightSpot, // 最右边的坐标数
    downSpot, //最下方的坐标数
  } = tetrisItemGenerate()

  // 弹出最终整合的对象信息（使用 俄罗斯方块成员坐标系插入颜色方法）
  // ================================================================
  return {
    name, // 筛选的成员名称
    stateName, // 方块类型的名称
    stateListLength, // 方块类型的长度
    color, // 颜色
    originList: [portrait, transverse], // 原点信息数组，为当前使用的坐标点
    allSpot: addColor(portrait, transverse, allSpot, color), // 总的坐标数
    leftSpot: addColor(portrait, transverse, leftSpot, color), // 最左边的坐标数
    rightSpot: addColor(portrait, transverse, rightSpot, color), // 最右边的坐标数
    downSpot: addColor(portrait, transverse, downSpot, color), //最下方的坐标数
  }
}

/**
 * @俄罗斯方块成员坐标系插入颜色方法
 * @portrait纵
 * @transverse列
 */
// ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
const addColor = (
  portrait: number,
  transverse: number,
  list: TetrisItemObjItemStateObjItems[],
  color?: string
) => {
  // 声明一个原始数组，对list参数map后返回的新数组进行接收
  // ================================================================
  let originalList = list.map((value) => {
    value.portrait += portrait
    value.transverse += transverse
    color && (value.color = color)

    return value
  })

  // 弹出修改后的数组信息
  // ================================================================
  return originalList
}

/**
 * @俄罗斯方块状态切换方法
 * @itemObj传入当前需要切换成员的对象信息
 */
// ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
export const tetrisItemSwitchState = (
  itemObj: InitializationTetrisItemReturn
) => {
  // 如果是只有一个坐标长度，直接跳出，不用后续计算
  // ================================================================
  if (itemObj.stateListLength === 1) {
    return
  }

  // 首先根据已有的俄罗斯方块变化规则数组来看，直接创建改变的规则对象，即根据规则数组依次取反
  // ================================================================
  const switchStateOne = { top: 'down', down: 'top' }
  const switchStateTwo = {
    top: 'right',
    right: 'down',
    down: 'left',
    left: 'top',
  }

  // 然后根据传入的状态数组长度进行匹配对应的规则信息，在传入当前的状态参数
  // ================================================================
  const switchState =
    itemObj.stateListLength === 2
      ? switchStateOne[itemObj.stateName]
      : switchStateTwo[itemObj.stateName]

  // 根据最初的俄罗斯方块数据对象中，获取到最初的当前改变后的状态信息，并对其数据进行结构
  // ================================================================
  const {
    allSpot, // 总的坐标数
    leftSpot, // 最左边的坐标数
    rightSpot, // 最右边的坐标数
    downSpot, //最下方的坐标数
  }: TetrisItemObjItemStateObjItem = deepClone(
    tetrisItemObj[itemObj.name].stateObj[switchState]
  )

  // 弹出已经处理好后的最新数据，并对坐标系进行更新
  // ================================================================
  return {
    name: itemObj.name, // 筛选的成员名称
    stateName: switchState, // 方块类型的名称
    stateListLength: itemObj.stateListLength, // 方块类型的长度
    originList: itemObj.originList, // 原点信息数组，为当前使用的坐标点
    color: itemObj.color, //颜色
    allSpot: addColor(
      itemObj.originList[0],
      itemObj.originList[1],
      allSpot,
      itemObj.color
    ), // 总的坐标数
    leftSpot: addColor(
      itemObj.originList[0],
      itemObj.originList[1],
      leftSpot,
      itemObj.color
    ), // 最左边的坐标数
    rightSpot: addColor(
      itemObj.originList[0],
      itemObj.originList[1],
      rightSpot,
      itemObj.color
    ), // 最右边的坐标数
    downSpot: addColor(
      itemObj.originList[0],
      itemObj.originList[1],
      downSpot,
      itemObj.color
    ), //最下方的坐标数
  }
}

/**
 * @俄罗斯方块位移函数
 * @portraitChangeNum纵变化量
 * @transverseChangeNum列变化量
 * @itemObj传入当前需要切换成员的对象信息
 */
// ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
export const tetrisItemDisplacement = (
  portraitChangeNum: number,
  transverseChangeNum: number,
  itemObj: InitializationTetrisItemReturn
) => {
  // 对 itemObj 参数进行结构方便使用
  // ================================================================
  const {
    name, // 筛选的成员名称
    stateName, // 方块类型的名称
    stateListLength, // 方块类型的长度
    color, //颜色
    originList, // 原点信息数组，为当前使用的坐标点
    allSpot, // 总的坐标数
    leftSpot, // 最左边的坐标数
    rightSpot, // 最右边的坐标数
    downSpot, //最下方的坐标数
  } = itemObj

  // 弹出修改后的对象数据
  // ================================================================
  return {
    name, // 筛选的成员名称
    stateName, // 方块类型的名称
    stateListLength, // 方块类型的长度
    color, //颜色
    originList: [
      originList[0] + portraitChangeNum,
      originList[1] + transverseChangeNum,
    ], // 原点信息数组，为当前使用的坐标点
    // 总的坐标数
    allSpot: tetrisItemDisplacementCalculation(
      portraitChangeNum,
      transverseChangeNum,
      allSpot
    ),
    // 最左边的坐标数
    leftSpot: tetrisItemDisplacementCalculation(
      portraitChangeNum,
      transverseChangeNum,
      leftSpot
    ),
    // 最右边的坐标数
    rightSpot: tetrisItemDisplacementCalculation(
      portraitChangeNum,
      transverseChangeNum,
      rightSpot
    ),
    //最下方的坐标数
    downSpot: tetrisItemDisplacementCalculation(
      portraitChangeNum,
      transverseChangeNum,
      downSpot
    ),
  }
}

/**
 * @俄罗斯方块位移配套函数
 * @portraitChangeNum纵变化量
 * @transverseChangeNum列变化量
 * @list需要修改位置的数据数组
 */
// ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
const tetrisItemDisplacementCalculation = (
  portraitChangeNum: number,
  transverseChangeNum: number,
  list: TetrisItemObjItemStateObjItems[]
) => {
  // 声明修改变量 modifyList ，用于承接list数据map后的新数组
  // ================================================================
  let modifyList = list.map((value) => {
    // 对现有数据中的位置信息进行对应相加
    value.portrait += portraitChangeNum
    value.transverse += transverseChangeNum

    return value
  })

  // 弹出已经处理好后的数据
  // ================================================================
  return modifyList
}
